package com.feilx.changgou.pay.service.impl;

import com.changgou.mq.MQConstant;
import com.changgou.utils.HttpClient;
import com.feilx.changgou.pay.service.WeixinPayService;
import com.github.wxpay.sdk.WXPayUtil;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;

@Service
public class WeixinPayServiceImp implements WeixinPayService {

    @Value("${weixin.appid}")
    private String  appid;  // 应用id
    @Value("${weixin.partner}")
    private String  partner; //商户id
    @Value("${weixin.partnerkey}")  // 秘钥
    private String  partnerkey;
    @Value("${weixin.notifyurl}")
    private String  notifyurl;   // 回调地址


    @Autowired
    private RabbitTemplate rabbitTemplate;

    /*
    *  实现扫码支付
    *
    * */
    @Override
    public Map createNative(Map<String, String> parameterMap) {
        try {

        Map<String,String>  map = new HashMap<>();
        map.put("appid",appid);
        map.put("mch_id",partner);
        // 随机字符串
        map.put("nonce_str", WXPayUtil.generateNonceStr());
        // 描述
        map.put("body","统一下单");
        // 订单号
        map.put("out_trade_no",parameterMap.get("out_trade_no"));
        // 交易金额
        map.put("total_fee",parameterMap.get("total_fee"));
        map.put("spbill_create_ip","127.0.0.1");
        map.put("notify_url",notifyurl);
        map.put("trade_type","NATIVE");

        // map 转换成XML字符串 可以携带签名
        String xmlparams = WXPayUtil.generateSignedXml(map, partnerkey);

        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder" ;

        // URL
        HttpClient httpClient = new HttpClient(url);
        // 提交方式 https
        httpClient.setHttps(true);
        // 提交参数
        httpClient.setXmlParam(xmlparams);

        // 执行请求
        httpClient.post();
        // 获取请求数据
        String content = httpClient.getContent();

        // 数据转换map
        Map<String, String> resultMap = WXPayUtil.xmlToMap(content);
        return  resultMap;
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Map queryWeixinPayStatus(String outtradeno) {
        try {

            Map<String,String>  map = new HashMap<>();
            map.put("appid",appid);
            map.put("mch_id",partner);
            // 随机字符串
            map.put("nonce_str", WXPayUtil.generateNonceStr());
            // 订单号
            map.put("out_trade_no",outtradeno);

            // map 转换成XML字符串 可以携带签名
            String xmlparams = WXPayUtil.generateSignedXml(map, partnerkey);

            String url = "https://api.mch.weixin.qq.com/pay/orderquery" ;

            // URL
            HttpClient httpClient = new HttpClient(url);
            // 提交方式 https
            httpClient.setHttps(true);
            // 提交参数
            httpClient.setXmlParam(xmlparams);

            // 执行请求
            httpClient.post();
            // 获取请求数据
            String content = httpClient.getContent();

            // 数据转换map
            Map<String, String> resultMap = WXPayUtil.xmlToMap(content);
            return  resultMap;
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    // 微信支付结果通知回调方法
    @Override
    public String notifyUrl(HttpServletRequest request) {
        ServletInputStream is = null;
        ByteArrayOutputStream os = null;
        try{
            // 获取网络输入流
            is = request.getInputStream();
            os = new ByteArrayOutputStream();
            //定义缓冲区
            byte[] b = new byte[1024];
            int len = 0;
            while((len = is.read(b))!=-1){
                os.write(b,0,len);
            }
            // 将支付回调数据转换成xml字符串
            String result = new String(os.toByteArray(),"utf-8");

            // 将xml字符串转换成Map结构
            Map<String,String> map = WXPayUtil.xmlToMap(result);

            // 通知订单微服务
            sendWeixinZfMsg(map);

            Map<String,String> resultMap = new HashMap();
            // 获取回调数据  通过 mq 通知 订单服务
            resultMap.put("return_code","SUCCESS");
            resultMap.put("return_msg","OK");
            return WXPayUtil.mapToXml(resultMap);

        }catch (Exception e){
            e.printStackTrace();
        }
        // 需要返回为微信支付服务器的数据
        String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        return result;
    }

    // MQ 向订单模块发送支付消息
    private void sendWeixinZfMsg(Map map){
        rabbitTemplate.convertAndSend(MQConstant.ORDER_EXCHANGE,MQConstant.ORDER_ROUTINGKEY,map.toString());
    }


}
